package gorpc

import (
	"gorpc/pb"

	"google.golang.org/protobuf/proto"
)

// PacketType 定义消息包类型
type PacketType = pb.PacketType

// 包类型常量
const (
	PacketType_Request  = pb.PacketType_Request
	PacketType_Response = pb.PacketType_Response
	PacketType_RpcIssue = pb.PacketType_RpcIssue
)

// Packet 表示一个消息包
type Packet struct {
	Type   PacketType
	Method string
	Body   []byte
	SeqID  int32
	Error  string
}

// Encode 将消息包编码为字节流
func (p *Packet) Encode() ([]byte, error) {
	pbPacket := &pb.Packet{
		PacketType: p.Type,
		Method:     p.Method,
		Context:    p.Body,
	}

	switch p.Type {
	case PacketType_Request:
		pbPacket.Request = &pb.RequestPacket{
			SeqId: p.SeqID,
		}
	case PacketType_Response:
		pbPacket.Response = &pb.ResponsePacket{
			SeqId: p.SeqID,
			Error: p.Error,
		}
	}

	return proto.Marshal(pbPacket)
}

// Decode 从字节流解码消息包
func (p *Packet) Decode(data []byte) error {
	pbPacket := &pb.Packet{}
	if err := proto.Unmarshal(data, pbPacket); err != nil {
		return err
	}

	p.Type = pbPacket.PacketType
	p.Method = pbPacket.Method
	p.Body = pbPacket.Context

	switch p.Type {
	case PacketType_Request:
		if pbPacket.Request != nil {
			p.SeqID = pbPacket.Request.SeqId
		}
	case PacketType_Response:
		if pbPacket.Response != nil {
			p.SeqID = pbPacket.Response.SeqId
			p.Error = pbPacket.Response.Error
		}
	}

	return nil
}
